Skip to content

fix(spi): harden SQL execution and connection lifecycle#1924

Merged
openai0229 merged 16 commits into
OtterMind:mainfrom
HandSonic:fix/spi-core
Jul 25, 2026
Merged

fix(spi): harden SQL execution and connection lifecycle#1924
openai0229 merged 16 commits into
OtterMind:mainfrom
HandSonic:fix/spi-core

Conversation

@HandSonic

@HandSonic HandSonic commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Related issue

N/A - this is a contributor maintenance PR without a separately tracked issue.

Summary

Hardens Community SPI SQL execution and pooled-connection lifecycle behavior, while retaining several focused correctness fixes from the original contribution.

The final change:

  • preserves caller transaction ownership in fetchAllTableRecords, rolls back failures, restores the original autoCommit state, and forcibly aborts a connection when rollback cannot be completed safely;
  • closes the ResultSet used by count();
  • prevents dead, duplicate, full-queue, removed-pool, and stale-generation connections from being leaked or returned to the wrong pool;
  • invalidates outstanding connection leases when a datasource pool is removed;
  • aligns ConnectInfo.hashCode() with equals() while keeping pool-generation state runtime-only;
  • reports an explicit error for an unregistered dbType and logs failures from setCatalog() / setSchema();
  • returns the MySQL column extent value correctly and checks the SQL Server schema name when building qualified table names.

Maintainer follow-up commits add transaction-ownership, rollback/abort, bounded-queue, cleanup-race, stale-lease, and generation-invalidation coverage.

Affected surfaces

  • Frontend / Web
  • Backend / API / Storage
  • Database plugin / Driver
  • JCEF / Desktop packaging
  • CI / Build / Release
  • Documentation only

Verification

  • Commands and results:
    • rtk mvn -pl chat2db-community-plugins/chat2db-community-mysql,chat2db-community-plugins/chat2db-community-sqlserver -am test -Dmaven.test.skip=false from chat2db-community-server: BUILD SUCCESS; Tools 26, SPI 73, MySQL 607, SQL Server 38; 744 tests total, 0 failures, 0 errors, 0 skipped.
    • rtk git diff --check origin/main...HEAD: passed.
  • Manual verification: N/A - lifecycle and SQL-builder behavior is covered by automated unit and concurrency tests.
  • UI evidence: N/A

Risk and compatibility

  • Public API or stored data: No API or stored-data format changes.
  • Database or driver compatibility: Corrects MySQL extent and SQL Server qualified-name generation; transaction cleanup now follows the connection's original ownership state.
  • Network, privacy, or security: No network or privacy contract changes. Failed rollback paths now abort the physical connection before fallback close so an indeterminate transaction is never reused.
  • Community / Local / Pro boundary: Community server SPI and Community MySQL / SQL Server plugins only.
  • Backward compatibility: Existing method signatures are unchanged. Stale or orphaned pooled connections are now closed instead of being reused or leaked.

Reviewer map

  • Start here: ConnectionPool, then DefaultSQLExecutor.fetchAllTableRecords; focused tests are ConnectionPoolTest and DefaultSQLExecutorTransactionTest.
  • Failure condition: a removed datasource generation can accept an old lease, a full queue can leak a connection, or rollback/restore failure can return an unsafe connection to the pool.
  • Rollback or disable path: revert this PR; no data migration or feature flag is involved.

Contributor declaration

  • I linked the Issue that defines this change. N/A - no separate issue was filed for this maintenance batch.
  • I tested the affected behavior and reported the actual results above.
  • I did not include credentials, private data, or generated build output.
  • I disclosed substantial AI assistance below, or this PR contains no substantial AI-generated code.

AI assistance: OpenAI Codex materially assisted the maintainer review, follow-up fixes, and test additions.

@openai0229 openai0229 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please split this PR into focused changes. It currently bundles nine unrelated fixes across connection-pool concurrency, transaction state, SQL generation, SQL Server schema handling, equality/hash behavior, and plugin lookup. These areas have different failure modes and need independent tests and rollback boundaries.

In particular, please add concurrency coverage for connection cleanup/queue behavior; preserve and restore the caller's original autoCommit state instead of forcing true; and test commit/rollback behavior around connection failures. The MySQL extent, SQL Server schema, equals/hashCode, and plugin lookup changes also need focused coverage.

The count SQL fix overlaps #1966. Please remove it here and let the smaller #1966 land independently.

buildExt() checked column.getExtent() for emptiness but returned
column.getComment() — a copy-paste error from buildComment() above it.
…eName()

The second condition duplicated the first, checking databaseName twice.
When databaseName was blank but schemaName was not, the schema was skipped.
Empty catch blocks silently swallowed failures when setting catalog or
schema, leaving the connection pointing at the wrong database with no
indication of the problem.
- Cleanup thread now calls iterator.remove() after closing stale/dead
  connections, preventing unbounded queue growth
- getConnection() returns ConnectInfo to queue when trySetInUse() fails,
  preventing connection leaks under concurrency
equals() compared {dataSourceId, gmtModified} but hashCode() used
{dataSourceId, consoleId, databaseName}, violating the Java contract.
Objects that are equal must have the same hashCode.
- ResultSet now in try-with-resources to prevent cursor leak
- catch block calls connection.rollback() on failure
- finally block restores connection.setAutoCommit(true) regardless of outcome
Previously, exceptions left the connection in autoCommit=false with no rollback.
ResultSet from stmt.getResultSet() was not explicitly closed. Some JDBC
drivers do not auto-close ResultSets when the parent Statement is closed,
leading to cursor leaks under repeated use.
@HandSonic

Copy link
Copy Markdown
Contributor Author

Updated the PR per review feedback:

  1. Removed SqlUtils count fix — overlaps Fix count SQL semicolon trimming #1966, skipped during rebase
  2. Fixed autoCommit restore — now saves connection.getAutoCommit() before modifying and restores the original value in finally, instead of forcing true
  3. Rebased on current main — reduced from 9 to 8 commits, 7 files changed

The remaining focused changes are:

  • MySQL buildExt() returns wrong value (1 line)
  • SQL Server buildTableName() wrong condition (1 line)
  • DefaultDBManager swallowed SQLException (2 lines)
  • ConnectionPool cleanup + leak (5 lines)
  • ConnectInfo hashCode alignment (1 line)
  • fetchAllTableRecords rollback + autoCommit restore (25 lines)
  • count() ResultSet leak (4 lines)
  • Chat2DBContext null check (16 lines)

PLUGIN_MAP.get(dbType) returned null for unknown types, causing opaque
NPE. Now throws IllegalArgumentException with the unsupported type name
and list of registered types.
@openai0229 openai0229 changed the title fix(spi): 9 fixes for connection pool, SQL execution, and context fix(spi): harden SQL execution and connection lifecycle Jul 25, 2026
@openai0229 openai0229 moved this to In Review in Chat2DB Community Jul 25, 2026

@openai0229 openai0229 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maintainer follow-up completed. Transaction ownership, rollback/abort cleanup, bounded queue handling, cleanup races, and stale lease invalidation are covered by focused tests. Final local reactor: 744 tests passed; diff check passed.

@openai0229
openai0229 merged commit f81b949 into OtterMind:main Jul 25, 2026
17 checks passed
@openai0229 openai0229 moved this from In Review to Done in Chat2DB Community Jul 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants